package com.scwatch.core.service.impl;

import com.scwatch.common.orm.LimitRequest;
import com.scwatch.common.orm.Limitable;
import com.scwatch.core.constant.Constants;
import com.scwatch.core.domain.*;
import com.scwatch.core.html.HtmlService;
import com.scwatch.core.listener.InfoListener;
import com.scwatch.core.repository.InfoDao;
import com.scwatch.core.repository.InfoDetailDao;
import com.scwatch.core.repository.InfoNodeDao;
import com.scwatch.core.repository.NodeDao;
import com.scwatch.core.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional(readOnly =false)
public class FlashBigNewServiceImpl implements FlashBigNewService {

	private InfoNodeDao dao;
	private  InfoDao infoDao;
	private NodeDao nodeDao;
	private InfoService infoService;
    private InfoQueryService infoQuery;
    private HtmlService htmlService;
    private List<InfoListener> listeners;

    private ModelService modelService;

    private NodeQueryService nodeQuery;

    private SiteService siteService;


    private InfoDetailDao detailDao;

    @Autowired
    public void setDetailDao(InfoDetailDao detailDao) {
        this.detailDao = detailDao;
    }

    @Autowired
    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

    @Autowired
    public void setNodeDao(NodeDao nodeDao) {
        this.nodeDao = nodeDao;
    }

    @Autowired
    public void setInfoQuery(InfoQueryService infoQuery) {
        this.infoQuery = infoQuery;
    }

    @Autowired
    public void setModelService(ModelService modelService) {
        this.modelService = modelService;
    }

    @Autowired
    public void setNodeQuery(NodeQueryService nodeQuery) {
        this.nodeQuery = nodeQuery;
    }

    @Autowired(required = false)
    public void setListeners(List<InfoListener> listeners) {
        this.listeners = listeners;
    }

    @Autowired
    public void setHtmlService(HtmlService htmlService) {
        this.htmlService = htmlService;
    }

    @Autowired
    public void setQuery(InfoQueryService infoQuery) {
        this.infoQuery = infoQuery;
    }

    @Autowired
    public void setInfoService(InfoService infoService) {
        this.infoService = infoService;
    }

	@Autowired
	public void setDao(InfoNodeDao dao) {
		this.dao = dao;
	}

    @Autowired
    public void setInfoDao(InfoDao infoDao) {
        this.infoDao = infoDao;
    }

    @Autowired
    public void setInfoDao(NodeDao nodeDao) {
        this.nodeDao = nodeDao;
    }

    @Override
    public void add(Integer siteId) {
       System.out.println("--------falsh runing start---------");
       if(siteId==null){
           return;
       }
       Site site = siteService.get(siteId);
       Integer sourceNodeId=null;
       Integer targetNodeId=null;

       Integer [] sourceIds=getNodeIdsByFlag(Constants.MODEL_FLAG_CURRENTNEWS,site,null);
       Integer [] targetIds=getNodeIdsByFlag(Constants.MODEL_FLAG_NEWSFLASH,site,null);

       if(sourceIds!=null && targetIds!=null && sourceIds.length>0 && targetIds.length>0 ){
           sourceNodeId=sourceIds[0];
           targetNodeId=targetIds[0];
       }

       if(sourceNodeId==null || targetNodeId==null){
           return;
       }
       List<Integer> sourceNodeIds=new ArrayList<>();
       sourceNodeIds.add(sourceNodeId);

        List<Integer> targetNodeIdList=new ArrayList<>();
        targetNodeIdList.add(targetNodeId);
	    List<Info> targetInfos=infoDao.findByNodeIdIn(targetNodeIdList);
	    if(targetInfos!=null){
            for(Info info:targetInfos){
                infoService.delete(info.getId());
            }
        }

        Sort defSort = new Sort(Sort.Direction.DESC, "priority","publishDate");
        Limitable limitable = new LimitRequest(null,3, defSort);
//        List<Info> sourceInfos =infoQuery.findList(null,sourceIds, null,
//                null, null,new Integer[]{site.getId()},null,null, null,
//                null,null, null, null, null,
//                null, null, null, null, null,
//                null, null, null,new String[]{"A"},null, null,
//                null, null, null, null, null, null, limitable);
        List<Info> sourceInfos =infoDao.findList(null,sourceIds, null,
                null, null,new Integer[]{site.getId()},null,null, null,
                null,null, null, null, null,
                null, null, null, null, null,
                null, null, null,new String[]{"A"},null, null,
                null, null, null, null, null, null, limitable,null);

        if(sourceInfos==null || sourceInfos.size()==0){
            return;
        }
        for(Info info:sourceInfos){

//            Info info1 = new Info();
//            try {
//
//                info1.setId(null);
//                info1.setNode(targetNode);
//
//                info1.setInfoNodes(null);
//                BeanUtils.copyProperties(info1,info);
//
//                InfoDetail infoDetail = info1.getDetail();
//                InfoDetail infoDetail1 = new InfoDetail();//insert
//                BeanUtils.copyProperties(infoDetail1,infoDetail);
//                info1.setDetail(null);
//                info1.setInfoNodes(null);
//
//
//                InfoBuffer infoBuffer = info1.getBuffer();
//                InfoBuffer infoBuffer1 =new InfoBuffer();//
//                BeanUtils.copyProperties(infoBuffer1,infoBuffer);
//                info1.setBuffer(null);
//                infoBuffer1.setInfo(null);
//
//                info1.setBuffers(null);
//
//
//                Map<String, String> clobsMap =  info1.getClobs();
//                Map<String, String> clobsMap1 =  new HashMap<>();
//                BeanUtils.copyProperties(clobsMap1,clobsMap);
//                info1.setClobs(null);
//
//
//                info1=infoDao.save(info1);
//                infoDetailService.save(infoDetail1,info1);
////                infoBufferService.save(infoBuffer1,info1);
//
////            InfoNode.
//            } catch (IllegalAccessException e) {
//                e.printStackTrace();
//            } catch (InvocationTargetException e) {
//                e.printStackTrace();
//            }
            Info newInfo=new Info();
            InfoDetail detail=new InfoDetail();
            detail.setTitle(info.getDetail().getTitle());
            detail.setLink(info.getDetail().getLink());

            newInfo.setStatus("A"); //正常，已发布
            newInfo.setNewsType(info.getNewsType());
            newInfo.setPriority(info.getPriority());
            newInfo.setIswatch(info.getIswatch());
            newInfo.setClobs(info.getClobs());
            newInfo.setComments(info.getComments());
            newInfo.setPublishDate(info.getPublishDate());
//            newInfo.setCustoms(info.getCustoms());
            newInfo.setDiggs(info.getDiggs());
//            newInfo.setWithImage(info.getWithImage());
            Info result=infoService.save(newInfo, detail, targetIds, null, null, null,null,null, null, null, null,
                        null, null, null, targetNodeId, info.getCreator().getId(), info.getStatus(), siteId);
//            htmlService.makeInfo(result);

        }
//        htmlGenerator.makeInfo(site.getId(), queryNodeId,queryNode.getName(),true, user.getId());
//        htmlGenerator.makeNode(site.getId(), queryNodeId,queryNode.getName(), true, user.getId());
        htmlService.makeNode(targetNodeId);
        System.out.println("--------falsh runing end---------");

    }



    private Integer[] getNodeIdsByFlag(String modelFlag, Site site,User user) {
        Integer [] nodeIds=null;
        Map<String,String[]> paramMap=new HashMap<String,String[]>();
        paramMap.put("EQ_flag",new String[]{modelFlag});
        List<Model> models=modelService.findList(site.getId(),null,paramMap,null);

        paramMap=new HashMap<String,String[]>();
        String[] idsStr;
        if(models!=null && models.size()>0){
            idsStr=new String[models.size()];
            for(int i=0;i<models.size();i++){
                idsStr[i]=models.get(i).getId().toString();
            }
            paramMap.put("EQ_nodeModel.id",idsStr);
        }
        Sort paramSort=new Sort(Sort.Direction.ASC, "treeNumber", "id");
        List<Node>  currentNodeList=nodeQuery.findList(site.getId(),null,
                null,null,true,
                paramMap, paramSort);
//        currentNodeList= user.getInfoPermList(site.getId(), currentNodeList);
        if(currentNodeList!=null){
            nodeIds=new Integer[currentNodeList.size()];
            for(int i=0;i<currentNodeList.size();i++){
                nodeIds[i]=(currentNodeList.get(i).getId());
            }
        }
        return  nodeIds;
    }

    private void firePostSave(Info bean) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoSave(bean);
            }
        }
    }

    private void updateHtml(Info bean, boolean toDelete) {
        Set<Info> beans = new HashSet<Info>();
        beans.add(bean);
        updateHtml(beans, toDelete);
    }

    private void updateHtml(Collection<Info> beans, boolean toDelete) {
        Set<Info> infos = new HashSet<Info>();
        Set<Node> nodes = new HashSet<Node>();
        Node node;
        for (Info bean : beans) {
            node = bean.getNode();
            node.updateHtmlStatus();
            nodes.add(node);

            bean.updateHtmlStatus();
            if (bean.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                infos.add(bean);
            }
            Integer id = bean.getId();
            Info next = infoQuery.findNext(id, false);
            Info prev = infoQuery.findPrev(id, false);
            if (next != null) {
                next.updateHtmlStatus();
                if (next.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                    infos.add(next);
                }
            }
            if (prev != null) {
                prev.updateHtmlStatus();
                if (prev.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                    infos.add(prev);
                }
            }
        }
        for (Info i : infos) {
            if (toDelete) {
                htmlService.deleteInfo(i);
            } else {
                htmlService.makeInfo(i);
            }
        }
        for (Node n : nodes) {
            htmlService.makeNode(n,null);
        }
    }
}
